package com.sprite.framework.entity;

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.sprite.framework.entity.condition.*;
import com.sprite.framework.entity.model.ModelEntityView;

/**
 * 	实体查询条件
 * @author Jack
 *
 */
public interface EntityCondition{
	void makeScript(DataScriptStatement script, ModelEntityView modelViewEntity) throws EntityException;

	default EntityCondition and(EntityCondition entityCondition){
		if(entityCondition == null){
			return this;
		}
		return EntityCondition.makeCondition(this, EntityJoinOperator.AND, entityCondition);
	}

	default EntityCondition or(EntityCondition entityCondition){
		if(entityCondition == null){
			return this;
		}
		return EntityCondition.makeCondition(this, EntityJoinOperator.OR, entityCondition);
	}

	static <R> EntityCondition notEqual(String fieldName, Object value) {
		return makeCondition(fieldName, EntityOperator.NOT_EQUALS, value);
	}

	static <R> EntityCondition in(String fieldName, Collection<?> values) {
		return makeCondition(fieldName, EntityOperator.IN, values);
	}

	static <R> EntityCondition in(String fieldName, MultiOperateValue values) {
		return makeCondition(fieldName, EntityOperator.IN, values);
	}
	static <R> EntityCondition like(String fieldName, String value) {
		return makeCondition(fieldName, EntityOperator.LIKE, value);
	}

	static <R> EntityCondition equal(String fieldName, Object value) {
		return makeCondition(fieldName, value);
	}

	static <R> EntityCondition gatherThan(String fieldName, Object value) {
		return makeCondition(fieldName, EntityOperator.GREATER_THAN, value);
	}
	
	static <R> EntityCondition gatherEqual(String fieldName, Object value) {
		return makeCondition(fieldName, EntityOperator.GREATER_THAN_EQUAL_TO, value);
	}
	
	static <R> EntityCondition lessThan(String fieldName, Object value) {
		return makeCondition(fieldName, EntityOperator.LESS_THAN, value);
	}
	
	static <R> EntityCondition lessEqual(String fieldName, Object value) {
		return makeCondition(fieldName, EntityOperator.LESS_THAN_EQUAL_TO, value);
	}
	
	static <R> EntityCondition fieldEqual(String fieldName, String field) {
		return makeCondition(fieldName, new NoParameterized(field, false));
	}
	
	static <R> EntityCondition isNull(String fieldName) {
		return makeCondition(fieldName, EntityOperator.IS_NULL, NoParameterized.NULL);
	}

	static <R> EntityCondition isNotNull(String fieldName) {
		return makeCondition(fieldName, EntityOperator.NOT_NULL, NoParameterized.NULL);
	}

	
	static <L, R, LL, RR> EntityExpr makeCondition(L l, EntityComparisonOperator<LL, RR> op, R r) {
		EntityExpr expr = new EntityExpr();
		expr.init(l, op, r);
		return expr;
	}

	static <R,T extends MultiOperateValue> EntityExpr makeCondition(String l, CollectionEntityComparisonOperator<T> op, Collection<R> r) {
		return makeCondition(l, op, new CollectionOperateValue(r));
	}

	static <R,T extends MultiOperateValue> EntityExpr makeCondition(String l, CollectionEntityComparisonOperator<T> op, MultiOperateValue r) {
		EntityExpr expr = new EntityExpr();
		expr.init(l, op, r);
		return expr;
	}

	static <R> EntityExpr makeCondition(String fieldName, R value) {
		return makeCondition(fieldName, EntityOperator.EQUALS, value);
	}

	static EntityExpr makeCondition(EntityCondition lhs, EntityJoinOperator operator, EntityCondition rhs) {
		EntityExpr expr = new EntityExpr();
		expr.init(lhs, operator, rhs);
		return expr;
	}

	static <T extends EntityCondition> EntityConditionList<T> makeCondition(EntityJoinOperator operator, List<T> conditionList) {
		EntityConditionList<T> ecl = new EntityConditionList<>();
		ecl.init(operator, conditionList);
		return ecl;
	}

	@SafeVarargs
	static <T extends EntityCondition> EntityConditionList<T> makeCondition(T... conditionList) {
		List<T> list=new LinkedList<>();
		if (conditionList != null) {
			for (T t : conditionList) {
				if (t!=null) {
					list.add(t);
				}
			}
		}

		EntityConditionList<T> ecl = new EntityConditionList<>();
		ecl.init(EntityOperator.AND, list);
		return ecl;
	}

	@SafeVarargs
	static <T extends EntityCondition> EntityConditionList<T> makeCondition(EntityJoinOperator op, T... conditionList) {
		EntityConditionList<T> ecl = new EntityConditionList<>();
		ecl.init(op, Arrays.asList(conditionList));
		return ecl;
	}

	static EntityFieldMap makeCondition(Map<String, ?> fieldMap) {
		EntityFieldMap efm = new EntityFieldMap();
		efm.init(fieldMap, EntityOperator.EQUALS, EntityOperator.AND);
		return efm;
	}

	EntityCondition AnyCondition = EntityCondition.makeCondition(new NoParameterized("1"), EntityOperator.EQUALS, "1");

	static EntityCondition any() {
		return AnyCondition;
	}

	static EntityCondition empty(){
		return EmptyCondition.getInstance();
	}
}
